﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace LSocket
{
    internal class LNet
    {
        Socket listenSocket;
        string localIP = "127.0.0.1";
        int localPort = 10001;
        SocketAsyncEventArgs acceptSAEA;

        internal LNet() {
            acceptSAEA = new SocketAsyncEventArgs();
            acceptSAEA.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptEventArg_Completed);
            listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            listenSocket.Bind(new IPEndPoint(IPAddress.Parse(localIP), localPort));
            listenSocket.Listen(100);

            ClientManager.Init();
            StartAccept();
        }

        private void StartAccept() {
            acceptSAEA.AcceptSocket = null;
            bool willRaiseEvent = listenSocket.AcceptAsync(acceptSAEA);
            if (!willRaiseEvent) {
                AcceptEventArg_Completed(null, acceptSAEA);
            }
        }

        void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e) {
            LClient client = ClientManager.AddClient(e.AcceptSocket);
            client.ReceiveSAEA.Completed += ReceiveSAEA_Completed;
            if (client == null) {
                Console.WriteLine("接收连接失败！");
            }
            else {
                StartReceive(client);
            }
            StartAccept();
        }

        void StartReceive(LClient client) {
            bool willRaiseEvent = client.ClientSock.ReceiveAsync(client.ReceiveSAEA);
            if (!willRaiseEvent) {
                ReceiveSAEA_Completed(null, client.ReceiveSAEA);
            }
        }

        private void ReceiveSAEA_Completed(object sender, SocketAsyncEventArgs e) {
            LClient client = e.UserToken as LClient;
            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success) {
                ClientManager.EnqueueNewCmd(client);
                StartReceive(client);
            }
            else {
                ClientManager.RemoveClient(client.ClientID);
                //CloseClientSocket(e);
            }
   
        }
    }


}
